package com.start.form.engine.core.tools;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.start.avue.AvueBaseFormColumn;
import com.start.form.engine.core.entity.StartFormConfig;
import com.start.form.engine.core.model.StartFormColumnModel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.start.form.engine.core.StartFormEngineConstant.FormBaseColumns.*;

public class StartAvueColTools {

    /**
     * 创建列信息
     *
     * @param prop  被追加字段：名称
     * @param label 被追加字段：中文名称
     * @param type  被追加字段：数据类型（数据库数据类型）
     * @param size  被追加字段：数据长度（数据库数据长度）
     * @return
     */
    public static AvueBaseFormColumn createColumn(String prop, String label, String type, Integer size) {
        StartFormColumnModel startFormColumn = StartFormColumnModel.createColumn(prop, label, type, size);
        AvueBaseFormColumn columnColumn = startFormColumn.createAvueColumn();
        columnColumn.setAddDetail(false);
        columnColumn.setAddDisplay(false);
        columnColumn.setEditDetail(false);
        columnColumn.setEditDisplay(false);
        columnColumn.setHide(true);
        columnColumn.setDisplay(false);
        return columnColumn;
    }

    /**
     * 自动追加系统默认列信息
     *
     * @param colMap 当前列信息map
     * @param column 当前正在操作的列信集合
     * @param prop   被追加字段：名称
     * @param label  被追加字段：中文名称
     * @param type   被追加字段：数据类型（数据库数据类型）
     */
    public static void autoAppendField(Map colMap, JSONArray column, String prop, String label, String type) {
        autoAppendField(colMap, column, prop, label, type, null, null);
    }

    /**
     * 自动追加系统默认列信息
     *
     * @param colMap 当前列信息map
     * @param column 当前正在操作的列信集合
     * @param prop   被追加字段：名称
     * @param label  被追加字段：中文名称
     * @param type   被追加字段：数据类型（数据库数据类型）
     * @param size   被追加字段：数据长度（数据库数据长度）
     */
    public static void autoAppendField(Map colMap, JSONArray column, String prop, String label, String type, Integer size) {
        autoAppendField(colMap, column, prop, label, type, size, null);
    }

    /**
     * 自动追加系统默认列信息
     *
     * @param colMap      当前列信息map
     * @param column      当前正在操作的列信集合
     * @param prop        被追加字段：名称
     * @param label       被追加字段：中文名称
     * @param type        被追加字段：数据类型（数据库数据类型）
     * @param size        被追加字段：数据长度（数据库数据长度）
     * @param appendIndex 追加的列集合中的位置
     */
    public static void autoAppendField(Map colMap, JSONArray column, String prop, String label, String type, Integer size, Integer appendIndex) {
        if (colMap.containsKey(prop)) {
            return;
        }
        AvueBaseFormColumn columnColumn = StartAvueColTools.createColumn(prop, label, type, size);
        if (appendIndex == null) {
            column.add(columnColumn.toOption());
            return;
        }
        column.add(appendIndex, columnColumn.toOption());
    }

    /**
     * 添加全局默认列信息
     *
     * @param map
     * @param column
     */
    public static void autoAppendGlobalField(Map map, JSONArray column) {
        StartAvueColTools.autoAppendField(map, column, COLUMN_PK_NAME, "主键", "varchar", 32, 0);
        StartAvueColTools.autoAppendField(map, column, COLUMN_CREATE_BY, "创建人", "varchar", 32);
        StartAvueColTools.autoAppendField(map, column, COLUMN_CREATE_START_USER_TYPE, "创建人用户类型", "varchar");
        StartAvueColTools.autoAppendField(map, column, COLUMN_CREATE_TIME, "创建时间", "timestamp");
        StartAvueColTools.autoAppendField(map, column, COLUMN_UPDATE_BY, "修改人", "varchar", 32);
        StartAvueColTools.autoAppendField(map, column, COLUMN_UPDATE_START_USER_TYPE, "修改人用户类型", "varchar", 100);
        StartAvueColTools.autoAppendField(map, column, COLUMN_UPDATE_TIME, "修改时间", "timestamp");
        StartAvueColTools.autoAppendField(map, column, COLUMN_DELETE_FLAG, "删除标记", "varchar", 20);
        StartAvueColTools.autoAppendField(map, column, COLUMN_FORM_OPTION_ID, "表单配置id", "varchar", 32);

    }

    /**
     * 获取表单配置中全部子表单配置
     *
     * @param config 主表配置
     * @return
     */
    public static List<JSONObject> getTableAvueDynamic(StartFormConfig config) {
        JSONObject formOption = config.getFormOption();
        if (formOption == null || formOption.isEmpty()) return new ArrayList<>();
        JSONArray column = formOption.getJSONArray("column");
        return getTableAvueDynamic(column);
    }

    /**
     * 获取表单配置中全部子表单配置
     *
     * @param column 主表中全部列信息
     * @return
     */
    public static List<JSONObject> getTableAvueDynamic(JSONArray column) {
        if (column == null || column.isEmpty()) return new ArrayList<>();
        return column.stream().map(e -> (JSONObject) e).filter(e -> "dynamic".equals(e.getString("type"))).collect(Collectors.toList());
    }

    /**
     * 根据主表获取子表配置信息
     *
     * @param mainTableConfig
     * @param dynamicCol
     * @return
     */
    public static StartFormConfig getAvueDynamicFormConfig(StartFormConfig mainTableConfig, JSONObject dynamicCol) {
        StartFormConfig dynamicTable = JSONObject.from(mainTableConfig).toJavaObject(StartFormConfig.class);
        String tableName = mainTableConfig.getTableName() + "_dynamic_" + dynamicCol.getString("prop");
        dynamicTable.setTableName(tableName);
        dynamicTable.setFormCode(tableName);
        dynamicTable.setFormCategory(tableName);
        dynamicTable.setFormOption(dynamicCol);
        dynamicTable.setParentId(mainTableConfig.getId());
        dynamicTable.setId(null);
        dynamicTable.setName(mainTableConfig.getName() + "-" + dynamicCol.getString("label"));
        return dynamicTable;
    }

    /**
     * 修改内容
     *
     * @param startFormColumns
     * @param tableOption
     */
    public static void updateTableOption(List<StartFormColumnModel> startFormColumns, JSONObject tableOption) {
        JSONArray column = tableOption.getJSONArray("column");
        Map<String, StartFormColumnModel> collect = startFormColumns.stream().collect(Collectors.toMap(StartFormColumnModel::getProp, e -> e));
        for (int i = 0; i < column.size(); i++) {
            JSONObject col = column.getJSONObject(i);
            if (!collect.containsKey(col.getString("prop"))) {
                continue;
            }
            if (col.containsKey("id")) {
                col.replace("id", collect.get(col.getString("prop")).getId());
            } else {
                col.put("id", collect.get(col.getString("prop")).getId());
            }
        }
    }
}
